home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
-
- /************************************************************************/
-
- #include "main.h"
- #include "File.h"
- #include "ProcessDir.h"
- #include "Includes.h"
- #include "Autodocs.h"
- #include "FormatNode.h"
- #include "AdditionalDocs.h"
-
- /************************************************************************/
-
- struct AVLTree IncludeFileTree =
- {NULL, (int (*)(struct AVLNode *, struct AVLNode *)) nodecasecmp};
- struct AVLTree StructureTree =
- {NULL, (int (*)(struct AVLNode *, struct AVLNode *)) nodecmp};
- struct AVLTree UnionTree =
- {NULL, (int (*)(struct AVLNode *, struct AVLNode *)) nodecmp};
- struct AVLTree TypedefTree =
- {NULL, (int (*)(struct AVLNode *, struct AVLNode *)) nodecmp};
- struct AVLTree DefinesTree =
- {NULL, (int (*)(struct AVLNode *, struct AVLNode *)) nodecmp};
-
- /************************************************************************/
- /* */
- /* Create a new IncludeItemNodeNode */
- /* */
- /************************************************************************/
-
- static struct IncludeItemNodeNode *
- CreateIncludeItem (char *Name,
- struct AVLTree *Tree,
- struct IncludeFileNode *IncludeFileNode,
- ULONG Line)
-
- {
- struct IncludeItemNode *IncludeItemNode;
- struct IncludeItemNodeNode *IncludeItemNodeNode;
- struct IncludeItemNodeNode **Current;
-
- if (!(IncludeItemNode = (struct IncludeItemNode *) SearchNode (Tree, Name)))
- {
- IncludeItemNode = (struct IncludeItemNode *) CreateNode (Name, sizeof (*IncludeItemNode));
- IncludeItemNode->Entries = NULL;
- IncludeItemNode->Function = FALSE;
- AVL_InsertNode (Tree, &IncludeItemNode->AnyNode.AVLNode);
- }
- IncludeItemNodeNode = xmalloc (sizeof (*IncludeItemNodeNode));
- IncludeItemNodeNode->IncludeFileNode = IncludeFileNode;
- IncludeItemNodeNode->IncludeItemNode = IncludeItemNode;
- IncludeItemNodeNode->Line = Line;
-
- Current = &(IncludeItemNode->Entries);
- while (*Current)
- {
- int Result;
-
- Result = strcasecmp ((*Current)->IncludeFileNode->AnyNode.Name,
- IncludeItemNodeNode->IncludeFileNode->AnyNode.Name);
- if (Result > 0)
- {
- break;
- }
- if (Result == 0)
- {
- if ((*Current)->Line > IncludeItemNodeNode->Line)
- {
- break;
- }
- }
- Current = &((*Current)->Next);
- }
- IncludeItemNodeNode->Next = *Current;
- *Current = IncludeItemNodeNode;
-
- return IncludeItemNodeNode;
- }
-
- /************************************************************************/
- /* */
- /* Write a word, creating links to #defines and typedefs */
- /* */
- /************************************************************************/
-
- void
- WriteIdentifier (struct Word *Word, struct IncludeFileNode *CurrentIncludeFile)
-
- {
- if (Pass2)
- {
- if (Word->Length > 1)
- {
- struct IncludeItemNode *IncludeItemNode;
-
- WriteWhitespace (Word);
-
- if ((IncludeItemNode = (struct IncludeItemNode *) SearchNode (&DefinesTree, Word->Word)) ||
- (IncludeItemNode = (struct IncludeItemNode *) SearchNode (&TypedefTree, Word->Word)))
- {
- struct IncludeItemNodeNode *IncludeItemNodeNode;
-
- IncludeItemNodeNode = IncludeItemNode->Entries;
- while (IncludeItemNodeNode && IncludeItemNodeNode->IncludeFileNode!=CurrentIncludeFile)
- {
- IncludeItemNodeNode=IncludeItemNodeNode->Next;
- }
- if (IncludeItemNodeNode)
- {
- WPrintf ("@{\x22%s\x22 LINK File %lu}",
- Word->Word, IncludeItemNodeNode->Line);
- }
- else
- {
- IncludeItemNodeNode=IncludeItemNode->Entries;
- WPrintf ("@{\x22%s\x22 LINK \x22%s/File\x22 %lu}",
- Word->Word,
- IncludeItemNodeNode->IncludeFileNode->LinkName,
- IncludeItemNodeNode->Line);
- }
- return;
- }
- }
- WriteWord (Word);
- }
- }
-
- /************************************************************************/
- /* */
- /* Read a C token, handling comments */
- /* */
- /************************************************************************/
-
- static struct Word *ReadToken (int AllowEOF, struct IncludeFileNode *CurrentIncludeFile)
-
- {
- struct Word *Word;
-
- do
- {
- Word = ReadWord (AllowEOF);
- if (Word->Word[0] == '/')
- {
- struct Word *NextWord;
-
- NextWord = ReadWord (FALSE);
- if (!NextWord->Whitespace && !NextWord->Newline && NextWord->Word[0] == '*')
- {
- /* found a comment */
- WriteWord (Word);
- FreeWord (Word);
- WriteWord (NextWord);
- FreeWord (NextWord);
- ConvertNodeText (TRUE, CurrentIncludeFile);
- Word = NULL;
- }
- else
- {
- UnreadWord (NextWord);
- }
- }
- }
- while (!Word);
- return Word;
- }
-
- /************************************************************************/
- /* */
- /* Look for the "current" node in a tree. */
- /* If that node is found, write it (creating a link if necessary). */
- /* If that node is not found, return NULL and don't write anything. */
- /* */
- /************************************************************************/
-
- static struct IncludeItemNodeNode *DoCurrentItem(struct IncludeFileNode *CurrentIncludeFile,
- ULONG CurrentLine,
- struct Word *Word,
- struct AVLTree *Tree,
- int CheckAutodocs)
-
- {
- struct IncludeItemNode *IncludeItemNode;
-
- if ((IncludeItemNode=(struct IncludeItemNode *)SearchNode(Tree,Word->Word)))
- {
- struct IncludeItemNodeNode *IncludeItemNodeNode;
-
- for (IncludeItemNodeNode=IncludeItemNode->Entries;
- (IncludeItemNodeNode &&
- (IncludeItemNodeNode->IncludeFileNode!=CurrentIncludeFile || IncludeItemNodeNode->Line!=CurrentLine));
- IncludeItemNodeNode=IncludeItemNodeNode->Next)
- ;
- if (IncludeItemNodeNode)
- {
- struct IncludeItemNodeNode *LinkDestNode;
-
- if ((LinkDestNode=IncludeItemNodeNode->Next))
- {
- DoIncludeLink:
- WriteWhitespace(Word);
- WPrintf ("@{\x22");
- WriteWord (Word);
- WPrintf ("\x22 LINK \x22");
- if (LinkDestNode->IncludeFileNode != CurrentIncludeFile)
- {
- WPrintf ("%s/", LinkDestNode->IncludeFileNode->LinkName);
- }
- WPrintf ("File\x22 %lu}", LinkDestNode->Line);
- }
- else
- {
- if (!CheckAutodocs || !DoAutodoc (Word, NULL))
- {
- LinkDestNode=IncludeItemNode->Entries;
- if (LinkDestNode->Next)
- {
- goto DoIncludeLink;
- }
- WriteWord (Word);
- }
- }
- }
- return IncludeItemNodeNode;
- }
- return NULL;
- }
-
- /************************************************************************/
- /* */
- /* Handle struct/union stuff */
- /* This function is expected to read the struct/union as first word */
- /* Returns the name of the variable (i.e. the last name before the ';' */
- /* */
- /************************************************************************/
-
- static struct Word *
- StructUnion (struct IncludeFileNode *CurrentIncludeFile)
-
- {
- static unsigned int BlockDepth;
- static struct IncludeItemNodeNode *CurrentStructure;
-
- struct Word *StartWord;
- struct Word *IdentifierWord;
- struct Word *Word;
- struct Word *VariableWord;
-
- if (!BlockDepth)
- {
- CurrentStructure = NULL;
- }
- BlockDepth++;
-
- VariableWord = NULL;
- StartWord = ReadWord (FALSE);
- WriteWhitespace (StartWord);
-
- IdentifierWord = ReadToken (FALSE, CurrentIncludeFile);
- if (IdentifierWord->Word[0] != '{')
- {
- /* named struct/union */
- /* struct Identifier ... */
-
- Word = ReadToken (FALSE, CurrentIncludeFile);
- if (Word->Word[0] != '{')
- {
- /* struct/union usage */
- /* struct Identifier Object */
-
- if (Pass2)
- {
- struct IncludeItemNode *IncludeItemNode;
-
- if ((IncludeItemNode = (struct IncludeItemNode *)
- SearchNode (StartWord->Word[0] == 'u' ?
- &UnionTree : &StructureTree,
- IdentifierWord->Word)))
- {
- struct IncludeItemNodeNode *IncludeItemNodeNode;
-
- for (IncludeItemNodeNode = IncludeItemNode->Entries;
- IncludeItemNodeNode && IncludeItemNodeNode!=CurrentStructure;
- IncludeItemNodeNode=IncludeItemNodeNode->Next)
- ;
- if (!IncludeItemNodeNode)
- {
- for (IncludeItemNodeNode=IncludeItemNode->Entries;
- IncludeItemNodeNode && IncludeItemNodeNode->IncludeFileNode!=CurrentIncludeFile;
- IncludeItemNodeNode=IncludeItemNodeNode->Next)
- ;
- if (!IncludeItemNodeNode)
- {
- IncludeItemNodeNode=IncludeItemNode->Entries;
- }
- if (!IdentifierWord->Newline)
- {
- WPrintf ("@{\x22");
- WriteWord (StartWord);
- }
- else
- {
- WriteWord (StartWord);
- WPrintf ("@{\x22");
- }
- WriteWord (IdentifierWord);
- if (CurrentIncludeFile == IncludeItemNodeNode->IncludeFileNode)
- {
- WPrintf ("\x22 LINK File %lu}", IncludeItemNodeNode->Line);
- }
- else
- {
- WPrintf ("\x22 LINK \x22%s/File\x22 %lu}",
- IncludeItemNodeNode->IncludeFileNode->LinkName,
- IncludeItemNodeNode->Line);
- }
- }
- else
- {
- WriteWord (StartWord);
- WriteWord (IdentifierWord);
- }
- }
- else
- {
- WriteWord (StartWord);
- WriteWord (IdentifierWord);
- }
- }
- do
- {
- WriteWord (Word);
- if (Word->Length > 1 || !Word->Special)
- {
- FreeWord (VariableWord);
- VariableWord = Word;
- }
- else
- {
- FreeWord (Word);
- }
- Word = ReadToken (FALSE, CurrentIncludeFile);
- }
- while (Word->Word[0] != ';' && Word->Word[0] != ')');
- UnreadWord (Word);
- FreeWord (IdentifierWord);
- FreeWord (StartWord);
- BlockDepth--;
- return VariableWord;
- }
- else
- {
- /* struct/union definition */
- /* struct Identifier {...} */
-
- WriteWord (StartWord);
- if (!Pass2)
- {
- if (BlockDepth == 1)
- {
- CurrentStructure=CreateIncludeItem (IdentifierWord->Word,
- StartWord->Word[0] == 'u' ? &UnionTree : &StructureTree,
- CurrentIncludeFile,
- StartWord->Line);
- }
- }
- else
- {
- if (BlockDepth==1)
- {
- CurrentStructure=DoCurrentItem(CurrentIncludeFile,
- StartWord->Line,
- IdentifierWord,
- StartWord->Word[0] == 'u' ? &UnionTree : &StructureTree,
- FALSE);
- }
- else
- {
- WriteWord (IdentifierWord);
- }
- }
- }
- WriteWord (Word);
- FreeWord (Word);
- }
- else
- {
- WriteWord (StartWord);
- }
- FreeWord (StartWord);
- FreeWord (IdentifierWord);
-
- /* Take care of the structure body */
- /* {...}; */
-
- Word = ReadToken (FALSE, CurrentIncludeFile);
- while (Word)
- {
- if (Word->Word[0] == '}')
- {
- WriteWord (Word);
- FreeWord (Word);
- Word = NULL;
- }
- else if (!strcmp (Word->Word, "struct") ||
- !strcmp (Word->Word, "union"))
- {
- UnreadWord (Word);
- FreeWord (StructUnion (CurrentIncludeFile));
- Word = ReadToken (FALSE, CurrentIncludeFile);
- }
- else
- {
- WriteIdentifier (Word, CurrentIncludeFile);
- if (Word->Length > 1 || !Word->Special)
- {
- FreeWord (VariableWord);
- VariableWord = Word;
- }
- else
- {
- FreeWord (Word);
- }
- Word = ReadToken (FALSE, CurrentIncludeFile);
- }
- }
- Word = ReadToken (FALSE, CurrentIncludeFile);
- while (Word->Word[0] != ';')
- {
- WriteWord (Word);
- if (Word->Length > 1 || !Word->Special)
- {
- FreeWord (VariableWord);
- VariableWord = Word;
- }
- else
- {
- FreeWord (Word);
- }
- Word = ReadToken (FALSE, CurrentIncludeFile);
- }
- UnreadWord (Word);
- BlockDepth--;
- return VariableWord;
- }
-
- /************************************************************************/
- /* */
- /* Functions to be called from FormatNode()/PrintLink() */
- /* */
- /************************************************************************/
-
- struct FormatParameters
- {
- struct IncludeFileNode *IncludeFileNode;
- struct AVLTree *Tree;
-
- struct AVLStateInfo StateInfo;
- struct IncludeItemNodeNode *IncludeItemNodeNode;
- };
-
- /************************************************************************/
-
- static char *
- NextLabel (char *PrevLabel, void *Parameters)
-
- {
- struct FormatParameters *Params;
- struct IncludeItemNode *IncludeItemNode;
-
- Params = Parameters;
-
- if (!PrevLabel)
- {
- AVL_InitTraversal (Params->Tree, &Params->StateInfo);
- }
- else
- {
- free (PrevLabel);
- }
-
- while ((IncludeItemNode=(struct IncludeItemNode *)AVL_InOrder(&Params->StateInfo)))
- {
- for (Params->IncludeItemNodeNode=IncludeItemNode->Entries;
- Params->IncludeItemNodeNode && Params->IncludeItemNodeNode->IncludeFileNode!=Params->IncludeFileNode;
- Params->IncludeItemNodeNode=Params->IncludeItemNodeNode->Next)
- ;
- if (Params->IncludeItemNodeNode)
- {
- char *Label, *t;
-
- Label=xmalloc(strlen(IncludeItemNode->AnyNode.Name)+3);
- t=stpcpy(Label,IncludeItemNode->AnyNode.Name);
- if (IncludeItemNode->Function)
- {
- stpcpy(t,"()");
- }
- return Label;
- }
- }
- return NULL;
- }
-
- /************************************************************************/
- /* */
- /* Print the link information */
- /* */
- /************************************************************************/
-
- static void
- PrintLink (void *Parameters)
-
- {
- struct IncludeItemNodeNode *IncludeItemNodeNode;
-
- IncludeItemNodeNode = ((struct FormatParameters *) Parameters)->IncludeItemNodeNode;
- WPrintf ("\x22%s/File\x22 %lu",
- IncludeItemNodeNode->IncludeFileNode->LinkName,
- IncludeItemNodeNode->Line);
- }
-
- /************************************************************************/
- /* */
- /* Output the table of contents */
- /* */
- /************************************************************************/
-
- static void
- WriteTOC (struct IncludeFileNode *IncludeFileNode)
-
- {
- int i;
-
- WPrintf ("\n@NODE MAIN \x22%s\x22\n", IncludeFileNode->AnyNode.Name);
- if (GlobalTOCFilename)
- {
- WPrintf("@TOC \x22%s/MAIN\x22\n",GlobalTOCFilename);
- }
- WPrintf ("\n@{\x22%s\x22 LINK File}\n", IncludeFileNode->AnyNode.Name);
-
- for (i=0; i<4; i++)
- {
- static struct
- {
- char *Header;
- struct AVLTree *Tree;
- } TOCParagraph[4]=
- {
- {"Structures",&StructureTree},
- {"Unions",&UnionTree},
- {"Typedefs",&TypedefTree},
- {"#defines",&DefinesTree}
- };
-
- struct FormatParameters FormatParameters;
- char *Label;
-
- FormatParameters.IncludeFileNode = IncludeFileNode;
- FormatParameters.Tree=TOCParagraph[i].Tree;
- if ((Label=NextLabel(NULL,&FormatParameters)))
- {
- int *ColWidth;
-
- free (Label);
- ColWidth = FormatNode (NextLabel, &FormatParameters);
- WPrintf (*Arguments.Version >= 39 ? "\n\n@{b}%s@{ub}\n\n" : "\n\n%s\n\n", TOCParagraph[i].Header);
- PrintNode (NextLabel, PrintLink, &FormatParameters, ColWidth);
- free (ColWidth);
- }
- }
- WPrintf ("\n@ENDNODE\n");
- }
-
- /************************************************************************/
- /* */
- /* Process a single include file. */
- /* */
- /************************************************************************/
-
- static void
- ProcessIncludeFile (struct IncludeFileNode *CurrentIncludeFile)
-
- {
- struct Word *Word;
- struct Word *TypedefWord, *TypedefName;
- ULONG DefineCount;
-
- DefineCount = 0;
-
- ROpen (INCLUDEDIR, CurrentIncludeFile->AnyNode.Name);
- WOpen (HYPERINCLUDEDIR, CurrentIncludeFile->AnyNode.Name);
-
- if (!Pass2)
- {
- CurrentIncludeFile->LinkName =
- Arguments.FullPath ? xstrdup (WriteFilename) : CurrentIncludeFile->AnyNode.Name;
- }
-
- WriteHeader (CurrentIncludeFile->LinkName, ReadFilename);
-
- if (Pass2)
- {
- WriteTOC (CurrentIncludeFile);
- }
-
- TypedefWord = TypedefName = NULL;
-
- WPrintf ("@NODE File \x22%s\x22\n", CurrentIncludeFile->AnyNode.Name);
- Word = ReadToken (FALSE, CurrentIncludeFile);
- while (Word->Length)
- {
- if (Word->Length == 1 && Word->Special)
- {
- /* one character special "words" */
- if (Word->Word[0] == '#')
- {
- /* Found a preprocessor command */
-
- WriteWord (Word);
- FreeWord (Word);
- Word = ReadWord (FALSE);
- WriteWord (Word);
- if (!strcmp (Word->Word, "include"))
- {
- /* #include */
- FreeWord (Word);
- Word = ReadWord (FALSE);
- if (Pass2)
- {
- if (Word->Word[0] == '"' || Word->Word[0] == '<')
- {
- char *Filename;
- struct IncludeFileNode *IncludeFileNode;
-
- WriteWord (Word);
- Filename = ReadUntil (Word->Word[0] == '"' ? "\x22" : ">");
- FreeWord (Word);
- Word = ReadWord (FALSE);
- if ((IncludeFileNode = (struct IncludeFileNode *) SearchNode (&IncludeFileTree, Filename)))
- {
- WPrintf ("@{\x22%s", Filename);
- WriteWhitespace (Word);
- WPrintf ("\x22 LINK \x22%s/File\x22}", IncludeFileNode->LinkName);
- }
- else
- {
- WPrintf ("%s", Filename);
- }
- WriteWord (Word);
- FreeWord (Word);
- Word = ReadWord (TRUE);
- free (Filename);
- }
- else
- {
- fprintf (stderr, "%s, line %lu;\nError: Illegal #include syntax\n",
- ReadFilename, Word->Line);
-
- SetRC (RETURN_ERROR);
- }
- }
- while (!Word->Newline)
- {
- WriteWord (Word);
- FreeWord (Word);
- Word = ReadWord (FALSE);
- }
- }
- else if (!strcmp (Word->Word, "define") && DefineCount++)
- {
- /* #define */
- FreeWord (Word);
- Word = ReadWord (FALSE);
- if (!Pass2)
- {
- struct IncludeItemNodeNode *IncludeItemNodeNode;
- struct Word *NextWord;
-
- IncludeItemNodeNode = CreateIncludeItem (Word->Word,
- &DefinesTree,
- CurrentIncludeFile,
- Word->Line);
- NextWord = ReadWord (FALSE);
- IncludeItemNodeNode->IncludeItemNode->Function =
- (!NextWord->Whitespace && !NextWord->Newline && NextWord->Word[0] == '(');
- UnreadWord (NextWord);
- }
- else
- {
- DoCurrentItem(CurrentIncludeFile, Word->Line, Word, &DefinesTree, TRUE);
- }
- FreeWord (Word);
- Word = ReadWord (TRUE);
- }
- else
- {
- /* Unknown preprocessor command */
- FreeWord (Word);
- Word = ReadWord (TRUE);
- while (Word->Length && !Word->Newline)
- {
- WriteWord (Word);
- FreeWord (Word);
- Word = ReadWord (TRUE);
- }
- }
- }
- else if (Word->Word[0] == ';')
- {
- if (TypedefWord)
- {
- if (TypedefName)
- {
- if (!Pass2)
- {
- CreateIncludeItem(TypedefName->Word,&TypedefTree,CurrentIncludeFile,TypedefWord->Line);
- }
- FreeWord (TypedefName);
- TypedefName=NULL;
- }
- FreeWord (TypedefWord);
- TypedefWord=NULL;
- }
- WriteWord (Word);
- FreeWord (Word);
- Word = ReadWord (TRUE);
- }
- else
- {
- WriteWord (Word);
- FreeWord (Word);
- Word = ReadWord (TRUE);
- }
- }
- else if (!strcmp (Word->Word, "struct") ||
- !strcmp (Word->Word, "union"))
- {
- UnreadWord (Word);
- TypedefName = StructUnion (CurrentIncludeFile);
- if (!TypedefWord)
- {
- FreeWord (TypedefName);
- TypedefName=NULL;
- }
- Word = ReadWord (TRUE);
- }
- else if (!strcmp (Word->Word, "typedef"))
- {
- WriteWord (Word);
- TypedefWord = Word;
- TypedefName = NULL;
- Word = ReadWord (FALSE);
- }
- else
- {
- if (TypedefWord)
- {
- struct Word *NextWord;
-
- NextWord = ReadToken (FALSE, CurrentIncludeFile);
- if (NextWord->Word[0] == ')' || NextWord->Word[0]==';')
- {
- TypedefName = Word;
- if (!DoCurrentItem(CurrentIncludeFile, TypedefWord->Line, Word, &TypedefTree, FALSE))
- {
- WriteWord (Word);
- }
- }
- else
- {
- WriteIdentifier (Word, CurrentIncludeFile);
- FreeWord (Word);
- }
- UnreadWord (NextWord);
- }
- else
- {
- WriteIdentifier (Word, CurrentIncludeFile);
- FreeWord (Word);
- }
- Word = ReadWord (TRUE);
- }
- UnreadWord (Word);
- Word = ReadToken (TRUE, CurrentIncludeFile);
- }
- FreeWord (Word);
- WPrintf ("\n@ENDNODE\n");
- WClose ();
- RClose ();
- }
-
- /************************************************************************/
- /* */
- /* Process a single include file, first pass. */
- /* */
- /************************************************************************/
-
- void
- ProcessIncludeFile1 (char *Filename)
-
- {
- struct IncludeFileNode *IncludeFileNode;
-
- IncludeFileNode = (struct IncludeFileNode *) CreateNode (Filename, sizeof (struct IncludeFileNode));
- AVL_InsertNode (&IncludeFileTree, (struct AVLNode *) IncludeFileNode);
- ProcessIncludeFile (IncludeFileNode);
- }
-
- /************************************************************************/
- /* */
- /* Process a single include file, second pass. */
- /* */
- /************************************************************************/
-
- void
- ProcessIncludeFile2 (struct IncludeFileNode *IncludeFileNode)
-
- {
- printf ("Converting %s\n", IncludeFileNode->AnyNode.Name);
- ProcessIncludeFile (IncludeFileNode);
- }
-